//
//  ViewController.m
//  ImagesDownload
//
//  Created by wanfu yan on 2017/7/9.
//  Copyright © 2017年 yanwanfu. All rights reserved.
//


#import "ViewController.h"
#import "YWFAppItem.h"

@interface ViewController ()

@property(nonatomic,strong)NSArray *apps;
@property(nonatomic,strong)NSMutableDictionary *images;
@property(nonatomic,strong)NSOperationQueue *queue; // 队列
@property(nonatomic,strong)NSMutableDictionary *operations; // 操作缓存

@end

@implementation ViewController



/**
 缓存操作

 @return return value description
 */
-(NSMutableDictionary*)operations{
    if (_operations == nil) {
        _operations = [NSMutableDictionary dictionary];
    }
    return _operations;
}


/**
 队列懒加载

 @return return value description
 */
-(NSOperationQueue*)queue{
    if (_queue == nil) {
        _queue = [[NSOperationQueue alloc]init];
        _queue.maxConcurrentOperationCount = 5;
    }
    return _queue;
}


/**
 内存缓存:应用退出缓存就清除
 
 @return return value description
 */
-(NSMutableDictionary*)images{
    if (_images == nil) {
        _images = [NSMutableDictionary dictionary];
        
    }
    return _images;
}


/**
 data source
 
 @return return value description
 */
-(NSArray*)apps{
    
    if (_apps == nil) {
        
        NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"apps.plist" ofType:nil]];
        
        NSMutableArray *mArray = [NSMutableArray array];
        for (NSDictionary *dict in array) {
            [mArray addObject:[YWFAppItem initWithDict:dict]];
            
        }
        _apps = mArray;
    }
    
    return _apps;
}


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

#pragma mark - tableview datasourece

/**
 组
 
 @param tableView tableView description
 @return return value description
 */
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}


/**
 行
 
 @param tableView <#tableView description#>
 @param section section description
 @return return value description
 */
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.apps.count;
}


/**
 行内容
 
 @param tableView tableView description
 @param indexPath indexPath description
 @return return value description
 */
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    static NSString * ID = @"app";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    //model
    YWFAppItem *item = self.apps[indexPath.row];
    
    //setup cell
    cell.textLabel.text = item.name;
    cell.detailTextLabel.text = item.download;
    
    // 1 从内存缓存读取图片
    UIImage *image = [self.images objectForKey:item.icon];
    if (image) {
        
        NSLog(@"内存缓存");
        
        cell.imageView.image = image;
   
    }else{
        
        // 2 从沙盒读取图片
        
        // 获取沙盒缓存目录路径
        NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
        // 获取文件名称,lastPathComponent:是url的最后一个节点，如：909099edkd.jpg
        NSString *filename = [item.icon lastPathComponent];
        // 拼接全路径（沙盒缓存目录路径+文件名）
        NSString *fullpath = [caches stringByAppendingPathComponent:filename];
        NSLog(@"%@",fullpath);
        
        ///检查沙盒缓存（这里使用NSData）
        NSData *imageData = [NSData dataWithContentsOfFile:fullpath];
        
        // 废除 调试用
        imageData = nil;
        
        if (imageData) {
            
            NSLog(@"磁盘缓存");
            
            UIImage *image = [UIImage imageWithData:imageData];
            cell.imageView.image = image;
            
            //从沙盒读取后再保存一份到内存，这样可以提高二次读取速度
            [self.images setObject: image forKey:item.icon]; //url作为key保存
            
        }else{
            // 3 从沙盒没有读取到，就执行下载操作
            
            
            //从缓存获取operation
            NSBlockOperation *downloadOperation = [self.operations objectForKey:item.icon];
            if (downloadOperation) {
                //等待下载完成,什么都不做
            }else{
                
                //先设置一个占位图片
                cell.imageView.image = [UIImage imageNamed:@"Snip20170710_14"];
                
                // 创建子线程下载
                downloadOperation = [NSBlockOperation blockOperationWithBlock:^{
                    NSLog(@"网上下载");
                    
                    NSURL *url = [NSURL URLWithString:item.icon];
                    NSData *imageData = [NSData dataWithContentsOfURL:url];
                    UIImage *image = [UIImage imageWithData:imageData];
                    
                    //容错：方式图片链接是错误的造成程序崩溃
                    if (!image) {
                        [self.operations removeObjectForKey:item.icon];
                        return;
                    }
                    
                    //写入内存缓存
                    [self.images setObject: image forKey:item.icon]; //url作为key保存
                    //写入沙盒缓存
                    [imageData writeToFile:fullpath atomically:YES];
                    //移除缓存的operation
                    [self.operations removeObjectForKey:item.icon];
                    
                    //更新UI，需要放在主线程（线程通信）
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                        //直接设置不显示图片，因为数据下载完成时tableViewCell已经创建出来，这个时候的image.size=0.
                        //cell.imageView.image = image;
                        //推荐使用刷新行来重新创建单行的cell,这个时候cell在装载数据时会从内存读取到下载好的image
                        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                        
                    }];
                    
                    
                    
                }];
                
                // 操作缓存,防止快速滑动屏幕，导致重复下载
                [self.operations setObject:downloadOperation forKey:item.icon];
                
                // 下载任务添加到队列里执行
                [self.queue addOperation:downloadOperation];

            }

        }
   
    }

    return cell;
    
}



/**
 当发生内存警告是清除所有缓存
 */
- (void)didReceiveMemoryWarning{
    [self.images removeAllObjects];
    [self.queue cancelAllOperations]; 
}

@end



/*
 补充知识点：
 
//NSCachesDirectory:    本地缓存目录
//NSUserDomainMask:     用户主目录
//YES:                  是否展开目录
//lastObject:           最后一个对象
NSLog(@"%@",[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]);

 缓存目录：
 Documents  : 手机连接iturns是会自动备份，禁止用于缓存，如果使用此目录，App审核会被拒绝
 Library    :
 Preferences : 保存偏好设置和账号
 caches      : 缓存文件
 
 tmp        : 临时路径，随时会被删除
 
 
*/
